{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://github.com/firecracker-microvm/firecracker/tree/main/docs/cpu-templates/schema.json",
    "title": "Custom CPU template",
    "description": "Custom CPU template language description",
    "type": "object",
    "properties": {
        "kvm_capabilities": {
            "type": "array",
            "items": {
                "description": "Additional KVM capabilities can be added or existing (built-in) capabilities can be removed from the firecracker checks. To add KVM capability to the checklist specify decimal number of the corresponding KVM capability. To remove a KVM capability from the checklist specify decimal number of the corresponding KVM capability with '!' mark in the front. Works on both x86_64 and aarch64.",
                "type": "string",
                "examples": ["171", "!172"]
            }
        },
        "vcpu_features": {
            "type": "array",
            "items": {
                "description": "vCPU features to enable during vCPU initialization. Only for aarch64.",
                "type": "object",
                "properties": {
                  "index": {
                        "description": "Index into kvm_vcpu_init::features array. As of Linux kernel 6.4.10, only value 0 is allowed.",
                        "type": "integer"
                  },
                  "bitmap": {
                        "description": "Bitmap for modifying the 32 bit field in kvm_vcpu_init::features. Must be in the format `0b[01x]{1,32}`. Corresponding bits will be cleared (`0`), set (`1`) or left intact (`x`). (`_`) can be used as a separator.",
                        "type": "string",
                        "examples": ["0b1100000"]
                  }
                }
            }
        },
        "cpuid_modifiers": {
            "type": "array",
            "items": {
                "description": "CPUID modifiers. Only for x86_64.",
                "type": "object",
                "properties": {
                    "leaf": {
                        "description": "CPUID leaf index (or function). Must be a string containing an integer.",
                        "type": "string",
                        "examples": ["0x1", "0x2"]
                    },
                    "subleaf": {
                        "description": "CPUID subleaf index (or subfunction). Must be a string containing an integer.",
                        "type": "string",
                        "examples": ["0x1", "0x2"]
                    },
                    "flags": {
                        "description": "KVM CPUID flags, see https://docs.kernel.org/virt/kvm/api.html#kvm-get-supported-cpuid",
                        "type": "integer"
                    },
                    "modifiers": {
                        "type": "array",
                        "items": {
                            "description": "CPUID register modifiers.",
                            "type": "object",
                            "properties": {
                                "register": {
                                    "description": "CPUID register name.",
                                    "type": "string",
                                    "enum": ["eax", "ebx", "ecx", "edx"]
                                },
                                "bitmap": {
                                    "description": "CPUID register value bitmap. Must be in format `0b[01x]{32}`. Corresponding bits will be cleared (`0`), set (`1`) or left intact (`x`). (`_`) can be used as a separator.",
                                    "type": "string",
                                    "examples": ["0bxxxx000000000011xx00011011110010", "0bxxxxxxxxxxxxx0xx00xx00x0_0000_00xx"]
                                }
                            }
                        }
                    }
                }
            }
        },
        "msr_modifiers": {
            "type": "array",
            "items": {
                "description": "MSR modifiers. Only for x86_64.",
                "type": "object",
                "properties": {
                    "addr": {
                        "description": "MSR address/identifier. Must be a string containing an integer.",
                        "type": "string",
                        "examples": ["0x10a"]
                    },
                    "bitmap": {
                        "description": "MSR value bitmap. Must be in format `0b[01x]{64}`. Corresponding bits will be cleared (`0`), set (`1`) or left intact (`x`). (`_`) can be used as a separator.",
                        "type": "string",
                        "examples": ["0bxxxx0000000000000000000000000000000000000000000000000000_11101011"]
                    }
                }
            }
        },
        "reg_modifiers": {
            "type": "array",
            "items": {
                "description": "ARM register modifiers. Only for aarch64.",
                "type": "object",
                "properties": {
                    "addr": {
                        "description": "ARM register address/identifier. Must be a string containing an integer. See https://docs.kernel.org/virt/kvm/api.html#kvm-set-one-reg .",
                        "type": "string",
                        "examples": ["0x603000000013c020"]
                    },
                    "bitmap": {
                        "description": "ARM register value bitmap. Must be in format `0b[01x]{1,128}`. The actual length of the bitmap should be less or equal to the size of the register in bits. Corresponding bits will be cleared (`0`), set (`1`) or left intact (`x`). (`_`) can be used as a separator.",
                        "type": "string",
                        "examples": ["0bxxxxxxxxxxxx_0000_xxxx_xxxx_xxxx_0000_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx"]
                    }
                }
            }
        }
    }
}
